#define _CRE_SECURE_NO_WARNINGS
#pragma once

#include "system_types.h"
#include "utils.h"

/**
 * 校园智能快递集散系统
 * 程序设计基础课程设计(2024级)
 *
 * 本文件包含通知系统相关功能实现
 */

/********** 接口清单 **********/

/**
 * @brief 添加通知到系统
 * 
 * 将一个新创建的通知对象添加到系统的通知链表中。
 * 如果通知ID已存在，则返回ERR_ALREADY_EXISTS错误。
 * 
 * @param data 系统数据结构指针
 * @param notification 要添加的通知对象指针
 * @return ErrorCode 
 *         - OK: 添加成功
 *         - ERR_INVALID_PARAM: 参数无效（data或notification为NULL）
 *         - ERR_ALREADY_EXISTS: 通知ID已存在
 *         - ERR_MEMORY: 内存分配失败
 */
ErrorCode addNotification(SystemData* data, Notification* notification);

/**
 * @brief 获取用户的通知列表
 * 
 * 根据指定的筛选条件，获取特定用户的通知列表。可以按照通知类型和已读状态进行筛选。
 * 
 * @param data 系统数据结构指针
 * @param userPhone 用户手机号码
 * @param type 通知类型（0表示全部类型）
 * @param readStatus 通知状态（0=全部, 1=未读, 2=已读）
 * @param resultList 结果列表数组指针，用于存储符合条件的通知指针
 * @param maxCount 最大返回结果数量
 * @return ErrorCode 
 *         - OK: 查询成功
 *         - ERR_INVALID_PARAM: 参数无效
 */
ErrorCode getUserNotifications(SystemData* data, const char* userPhone, NotificationType type,
    int readStatus, Notification** resultList, int maxCount);

/**
 * @brief 通过ID查找通知
 * 
 * 在系统中查找指定ID的通知对象。
 * 
 * @param data 系统数据结构指针
 * @param notificationID 通知ID
 * @return Notification* 找到的通知对象指针，未找到时返回NULL
 */
Notification* findNotificationByID(SystemData* data, const char* notificationID);

/**
 * @brief 通过ID删除通知
 * 
 * 从系统中删除指定ID的通知对象并释放内存。
 * 
 * @param data 系统数据结构指针
 * @param notificationID 通知ID
 * @return ErrorCode 
 *         - OK: 删除成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_NOT_FOUND: 未找到指定ID的通知
 */
ErrorCode removeNotificationByID(SystemData* data, const char* notificationID);

/**
 * @brief 生成唯一的通知ID
 * 
 * 生成格式为"NT+时间戳+随机数"的唯一通知ID。
 * 
 * @param notificationID 用于存储生成ID的缓冲区，大小应至少为MAX_NOTIFICATION_ID_LEN
 */
void generateNotificationID(char* notificationID);

/**
 * @brief 创建新的通知对象
 * 
 * 根据提供的通知类型、接收者手机号和包裹ID创建一个新的通知对象。
 * 自动生成通知ID并设置创建时间。
 * 
 * @param notificationType 通知类型
 * @param receiverPhone 接收者手机号
 * @param packageID 包裹ID
 * @return Notification* 创建的通知对象指针，失败时返回NULL
 */
Notification* generateNotification(int notificationType, const char* receiverPhone, const char* packageID);

/**
 * @brief 存储新通知到系统
 * 
 * 创建新通知并添加到系统中的便捷函数。
 * 
 * @param data 系统数据结构指针
 * @param type 通知类型
 * @param receiverPhone 接收者手机号
 * @param packageID 包裹ID
 * @return ErrorCode 
 *         - OK: 存储成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_MEMORY: 内存分配失败
 *         - ERR_ALREADY_EXISTS: 通知ID已存在
 */
ErrorCode storeNotification(SystemData* data, int type, const char* receiverPhone, const char* packageID);

/**
 * @brief 标记通知为已读
 * 
 * 将指定ID的通知标记为已读状态。
 * 
 * @param data 系统数据结构指针
 * @param notificationID 通知ID
 * @return ErrorCode 
 *         - OK: 标记成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_NOT_FOUND: 未找到指定ID的通知
 */
ErrorCode markNotificationAsRead(SystemData* data, const char* notificationID);

/**
 * @brief 清理过期通知
 * 
 * 删除系统中超过指定天数的通知，释放内存空间。
 * 
 * @param data 系统数据结构指针
 * @param dayThreshold 天数阈值，超过此天数的通知将被清理
 * @return ErrorCode 
 *         - OK: 清理成功
 *         - ERR_INVALID_PARAM: 参数无效
 */
ErrorCode cleanupExpiredNotification(SystemData* data, int dayThreshold);

/**
 * @brief 通知包裹状态变更
 * 
 * 根据包裹的新状态生成相应的通知发送给收件人。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @param status 新的包裹状态
 * @return ErrorCode 
 *         - OK: 通知成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_MEMORY: 内存分配失败
 */
ErrorCode notifyPackageStatusChange(SystemData* data, Package* package, PackageStatus status);

/**
 * @brief 通知包裹到达
 * 
 * 当包裹到达集散点时，向收件人发送通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackageArrival(SystemData* data, Package* package);

/**
 * @brief 通知包裹已取走
 * 
 * 当包裹被取走时，向收件人发送确认通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackagePickup(SystemData* data, Package* package);

/**
 * @brief 通知包裹运输中
 * 
 * 当包裹处于运输状态时，向收件人发送进度通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackageTransporting(SystemData* data, Package* package);

/**
 * @brief 通知包裹损坏
 * 
 * 当包裹被发现损坏时，向收件人发送异常情况通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackageDamaged(SystemData* data, Package* package);

/**
 * @brief 通知包裹丢失
 * 
 * 当包裹被确认丢失时，向收件人发送异常情况通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackageLost(SystemData* data, Package* package);

/**
 * @brief 通知包裹退回
 * 
 * 当包裹被退回时，向收件人发送通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 参见notifyPackageStatusChange函数
 */
ErrorCode notifyPackageReturned(SystemData* data, Package* package);

/**
 * @brief 通知错误取件
 * 
 * 当包裹被错误取走（非指定收件人取走）时，向正确收件人发送警告通知。
 * 
 * @param data 系统数据结构指针
 * @param package 包裹对象指针
 * @return ErrorCode 
 *         - OK: 通知成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_MEMORY: 内存分配失败
 */
ErrorCode notifyWrongPickup(SystemData* data, Package* package);

/**
 * @brief 生成取件提醒通知
 * 
 * 为系统中超过指定天数未取的包裹生成提醒通知。
 * 仅针对状态为"已通知"但未取走的包裹。
 * 
 * @param data 系统数据结构指针
 * @param daysThreshold 天数阈值，超过此天数未取的包裹将生成提醒
 * @return ErrorCode 
 *         - OK: 生成成功
 *         - ERR_INVALID_PARAM: 参数无效
 *         - ERR_MEMORY: 内存分配失败
 */
ErrorCode generatePickupReminders(SystemData* data, int daysThreshold);

